import agentFramework.action.Action;
import agentFramework.agent.Agent;
import agentFramework.core.Message;
import agentFramework.core.env.Environment;
import agentFramework.strategy.Strategy;
import agentFramework.utils.Debug;


public class DilemmaGuy extends Agent
{

	public DilemmaGuyPersonality	personality;
	public DilemmaGuy(int id, int coreId, DilemmaGuyPersonality p, Environment env) 
	{
		super(id, coreId, env);
		
		this.personality   = p;
		// no initial action
		this.currentAction = null;
	}

	@Override
	public void behavior() 
	{
		Debug.print(name + ": started");
		
		while (true)
		{
			if (this.isEnvironmentActive() == false)
			{
				/* stop this thread */
				break;
			}
			
			lock.lock();
			
			while (!messageQueue.isEmpty())
			{
				// get the first message
				Message msg = messageQueue.pollFirst();
				
				// leave the chance to receive messages
				lock.unlock();
				
				handleMessage(msg);
				
				lock.lock();
			}
			
			lock.unlock();
		}
	}

	@Override
	public void handleMessage(Message msg) 
	{
		Debug.print(name + ": message received: \n" + msg.toString());
		
		switch(msg.type)
		{
			case Message.TYPE_ADMINISTRATIVE:
			{
				if (Constants.MSG_CONTENT_MANIFEST_INTENTION.equals(msg.content))
				{
					// compute the decision 
					currentAction = agentStrategy.makeDecision();

					// create the template message
					Message replyMsg = new Message(getAgentId(), 
												   0, 
												   Message.TYPE_COMMON,
												   ((DilemmaAction)currentAction).toString()
												   );
					
					// send the intention to its neighbors
					for (Integer i : this.neighborList)
					{
						replyMsg.receiverID = i;
						sendMesage(replyMsg);
					}

					// inform the core that the task has been accomplished
					replyMsg = new Message(getAgentId(), 
										   coreId, 
										   Message.TYPE_ADMINISTRATIVE, 
										   Constants.MSG_CONTENT_DONE);
					
					this.sendMesage(replyMsg);
				}
				else if (Constants.MSG_CONTENT_PROCESS_REMAINING_MESSAGES.equals(msg.content))
				{
					lock.lock();
					
					// process all the queue
					while(!messageQueue.isEmpty())
					{
						Message 	queueMsg = messageQueue.pollFirst();
						Action 		action = DilemmaAction.toAction(queueMsg.content);
						
						agentStrategy.updateAgentDecision(msg.senderID, action);
					}
					
					lock.unlock();

					// compute the decision 
					currentAction = agentStrategy.makeDecision();
					
					// inform the core that the task has been accomplished
					Message replyMsg = new Message(getAgentId(), 
												   coreId, 
												   Message.TYPE_ADMINISTRATIVE, 
												   Constants.MSG_CONTENT_DONE);
		
					this.sendMesage(replyMsg);
				}
				else if (Constants.MSG_CONTENT_REVISE_STRATEGY.equals(msg.content))
				{
					agentStrategy.reviseStrategy();
					
					// inform the core that the task has been accomplished
					Message replyMsg = new Message(getAgentId(), 
												   coreId, 
												   Message.TYPE_ADMINISTRATIVE, 
												   Constants.MSG_CONTENT_DONE);
	
					this.sendMesage(replyMsg);					
				}
				
				break;
			}

			case Message.TYPE_COMMON:
			{
				Action action = DilemmaAction.toAction(msg.content);
				
				agentStrategy.updateAgentDecision(msg.senderID, action);
				
				// compute the decision 
				currentAction = agentStrategy.makeDecision();
				
				break;
			}

			default:
			{
				break;
			}
		}
	}
}
